package com.example.sharding.demo.config;

import com.example.sharding.demo.utils.DateUtil;
import com.google.common.collect.Range;
import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.RangeShardingValue;
import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
import io.shardingsphere.api.algorithm.sharding.standard.RangeShardingAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

/**
 * 分表规则
 * 按单月分表
 */
public class UserTableShardingAlgorithm implements PreciseShardingAlgorithm<Date>, RangeShardingAlgorithm<Date> {

    @Autowired
    private ShardDataSourceProperties properties;


    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> preciseShardingValue) {
        StringBuffer tableName = new StringBuffer();
        tableName.append(preciseShardingValue.getLogicTableName())
                .append("_").append(DateUtil.date2Str(preciseShardingValue.getValue(), DateUtil.YEAR_MONTH_NUMBER));
        return tableName.toString();
    }

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Date> rangeShardingValue) {
        Collection<String> targetNames = new ArrayList<String>();
        Range<Date> valueRange = rangeShardingValue.getValueRange();
        Integer lowerYear = null, upperYear = null;
        if (valueRange.hasLowerBound()) {
            lowerYear = Integer.parseInt(DateUtil.date2Str(valueRange.lowerEndpoint(), DateUtil.YEAR_MONTH_NUMBER));
        }
        if (valueRange.hasUpperBound()) {
            upperYear = Integer.parseInt(DateUtil.date2Str(valueRange.upperEndpoint(), DateUtil.YEAR_MONTH_NUMBER));
        }
        if (lowerYear == null) {
            lowerYear = Integer.parseInt(DateUtil.date2Str(DateUtil.str2Date(properties.getStartTime(),null), DateUtil.YEAR_MONTH_NUMBER));
        }
        if (upperYear == null) {
            lowerYear = Integer.parseInt(DateUtil.date2Str(new Date(), DateUtil.YEAR_MONTH_NUMBER));
        }
        for (String targetName : availableTargetNames) {
            for (int i = lowerYear; i <= upperYear; i++) {
                targetNames.add(targetName + "_" + i);
            }
        }
        return targetNames;
    }

}
